package com.wxyzz.satserver.follow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxyzz.common.core.common.PageParam;
import com.wxyzz.common.core.entity.FollowInfo;
import com.wxyzz.common.core.exception.CustmerException;
import com.wxyzz.common.core.utils.TokenUtils;
import com.wxyzz.common.redis.utils.RedisUtils;
import com.wxyzz.satserver.follow.dao.FollowDao;
import com.wxyzz.satserver.follow.service.FollowService;
import com.wxyzz.satserver.follow.vo.FanInfoVO;
import com.wxyzz.satserver.follow.vo.FollowInfoVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;


@Service
public class FollowServiceImpl implements FollowService {

    @Resource
    private FollowDao followDao;


    /**
     *  进行关注和取消关注
     * @param beFocusedId
     */
    @Override
    public void followUser(Integer beFocusedId) {
        // 获取用户id
        Integer uid = TokenUtils.getUidFromToken();

        // redis 中的key值
        String key = String.format("follow:%s", uid);
        // redis 中的 hash结构的key值
        String field = beFocusedId.toString();

        // 判断redis 中是否有关注信息
        Integer value = (Integer) RedisUtils.hashGet(key, field);
        if (value == null || value == 0) {
            // 存到redis中
            RedisUtils.hashPut(key, field, 1);
            // 查看 redis 中有没有对方关注自己的信息
            String key1 = String.format("follow:%s", beFocusedId);
            String field1 = uid.toString();
            Integer value1 = (Integer) RedisUtils.hashGet(key1, field1);

            if (value1 == null || value1 == 0) {
                if (value != null) {
                    // 修改数据库关注状态
                    int update = followDao.update(null, new LambdaUpdateWrapper<FollowInfo>()
                            .set(FollowInfo::getFollowStatus, 1)
                            .eq(FollowInfo::getFollowerId, uid)
                            .eq(FollowInfo::getBeFocusedId, beFocusedId));
                    if (update == 0) {
                        throw new CustmerException(500, "关注失败");
                    }
                } else {
                    // 存到数据库中
                    FollowInfo followInfo = new FollowInfo();
                    followInfo.setFollowerId(uid);
                    followInfo.setBeFocusedId(beFocusedId);
                    followInfo.setFollowStatus(1);
                    int insert = followDao.insert(followInfo);
                    if (insert == 0) {
                        throw new CustmerException(500, "关注失败");
                    }
                }

            } else {

                if (value != null) {
                    // 修改当前用户数据库的 关注状态 和回关状态
                    int update1 = followDao.update(null, new LambdaUpdateWrapper<FollowInfo>()
                            .set(FollowInfo::getFollowStatus, 1)
                            .set(FollowInfo::getBackTurn, 1)
                            .eq(FollowInfo::getFollowerId, uid)
                            .eq(FollowInfo::getBeFocusedId, beFocusedId));
                    if (update1 == 0) {
                        throw new CustmerException(500, "关注失败");
                    }
                    // 并且 修改对方的回关状态
                    int i1 = followDao.update(null, new LambdaUpdateWrapper<FollowInfo>()
                            .set(FollowInfo::getBackTurn, 1)
                            .eq(FollowInfo::getFollowerId, beFocusedId)
                            .eq(FollowInfo::getBeFocusedId, uid));
                    if (i1 == 0) {
                        throw new CustmerException(500, "关注失败");
                    }

                } else {
                    // 存到数据库中
                    FollowInfo followInfo = new FollowInfo();
                    followInfo.setFollowerId(uid);
                    followInfo.setBeFocusedId(beFocusedId);
                    followInfo.setFollowStatus(1);
                    followInfo.setBackTurn(1);
                    int insert = followDao.insert(followInfo);
                    if (insert == 0) {
                        throw new CustmerException(500, "关注失败");
                    }
                    // 修改对方的回关状态
                    int i1 = followDao.update(null, new LambdaUpdateWrapper<FollowInfo>()
                            .set(FollowInfo::getBackTurn, 1)
                            .eq(FollowInfo::getFollowerId, beFocusedId)
                            .eq(FollowInfo::getBeFocusedId, uid));
                    if (i1 == 0) {
                        throw new CustmerException(500, "关注失败");
                    }
                }
            }
        }
        // 取消关注
        else {
            RedisUtils.hashPut(key, field, 0);

            // 查看 redis 中有没有对方关注自己的信息
            String key1 = String.format("follow:%s", beFocusedId);
            String field1 = uid.toString();
            Integer v = (Integer) RedisUtils.hashGet(key1, field1);

            if (v == null || v == 0) {
                // 修改数据库 关注状态
                int i = followDao.update(null, new LambdaUpdateWrapper<FollowInfo>()
                        .set(FollowInfo::getFollowStatus, 0)
                        .eq(FollowInfo::getFollowerId, uid)
                        .eq(FollowInfo::getBeFocusedId, beFocusedId));
                if (i == 0) {
                    throw new CustmerException(500, "取消关注失败");
                }
            } else {

                // 修改数据库 关注状态和回关状态
                int i = followDao.update(null, new LambdaUpdateWrapper<FollowInfo>()
                        .set(FollowInfo::getFollowStatus, 0)
                        .set(FollowInfo::getBackTurn, 0)
                        .eq(FollowInfo::getFollowerId, uid)
                        .eq(FollowInfo::getBeFocusedId, beFocusedId));
                if (i == 0) {
                    throw new CustmerException(500, "取消关注失败");
                }
                // 修改对方的回关状态
                int i1 = followDao.update(null, new LambdaUpdateWrapper<FollowInfo>()
                        .set(FollowInfo::getBackTurn, 0)
                        .eq(FollowInfo::getFollowerId, beFocusedId)
                        .eq(FollowInfo::getBeFocusedId, uid));
                if (i1 == 0) {
                    throw new CustmerException(500, "取消回关失败");
                }
            }
        }


    }

    /**
     *  获取当前用户的 粉丝数
     * @return int
     */
    @Override
    public int beFocusedCount() {
        Integer uid = TokenUtils.getUidFromToken();
        // 通过关注表中的被关注对象 和 关注状态为 1
        // 来查询 当前用户被多少人关注
        Long l = followDao.selectCount(new LambdaQueryWrapper<FollowInfo>()
                .eq(FollowInfo::getBeFocusedId, uid)
                .eq(FollowInfo::getFollowStatus, 1));

        return Integer.valueOf(l.toString());
    }

    /**
     *  获取当前用户的 关注数
     * @return
     */
    @Override
    public int followCount() {
        Integer uid = TokenUtils.getUidFromToken();

        // 通过关注表中的关注对象 和 关注状态 1
        // 查询 当前用户关注了多少用户
        Long l = followDao.selectCount(new LambdaQueryWrapper<FollowInfo>()
                .eq(FollowInfo::getFollowerId, uid)
                .eq(FollowInfo::getFollowStatus, 1));

        return l.intValue();
    }

    /**
     *  获取 当前用户和 目标用户的关注状态
     * @param uid
     * @param beFocusedId
     * @return
     */
    @Override
    public int followStatus(Integer uid, Integer beFocusedId) {

        // 通过 follow_id 和 follow_beFocusedId 查询当前关注状态
        FollowInfo followInfo = followDao.selectOne(new LambdaQueryWrapper<FollowInfo>()
                .eq(FollowInfo::getFollowerId, uid)
                .eq(FollowInfo::getBeFocusedId, beFocusedId));

        if (followInfo != null) {
            return followInfo.getFollowStatus();
        }

        return 0;
    }

    /**
     * 获取 当前用户 的关注列表
     * @param param
     * @return
     */
    @Override
    public Page<FollowInfoVO> getFollowInfo(PageParam param) {
        Page<FollowInfoVO> page = new Page<>(param.getPage(), param.getPageSize());

        Integer uid = TokenUtils.getUidFromToken();
        Page<FollowInfoVO> followInfoVOPage = followDao.selectFollowInfo(page, uid);

        return followInfoVOPage;
    }

    @Override
    public Page<FanInfoVO> getFanInfo(PageParam param) {
        Integer uid = TokenUtils.getUidFromToken();
        Page<FanInfoVO> page = new Page<>(param.getPage(), param.getPageSize());
        Page<FanInfoVO> fanInfoVOPage = followDao.selectFanInfo(page, uid);

        return fanInfoVOPage;
    }
}
